﻿using blackhouse.WebNemo.Business;
using blackhouse.WebNemo.Business.Extensionable;
using blackhouse.WebNemo.Business.Groups;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace blackhouse.WebNemo.Web.Nemo.Manager {
    public partial class GroupPage : System.Web.UI.Page {

        #region Fields

        private Factory factory = Factory.Instance();
        private IGroup group;
        private NemoUrl stateUrl;
        private bool create;
        private GroupType createType;

        private Extensions extensions;
        private Type groupExtension;
        private Type recordExtension;

        #endregion

        #region Event Handlers

        protected override void OnInit(EventArgs e) {
            base.OnInit(e);

            this.SetScenario();
        }

        protected override void OnLoad(EventArgs e) {
            base.OnLoad(e);

            if (!IsPostBack)
                this.PopulateView();
        }

        #endregion

        #region Methods

        private void SetScenario() {
            this.stateUrl = new NemoUrl();
            if (this.stateUrl.GroupId > 0) {
                this.group = new Group(this.stateUrl.GroupId);
                if (this.group.Type == GroupType.Table) {
                    this.extensions = new Extensions(this.group);
                    this.groupExtension = extensions.GetGroupExtensionType();
                    this.recordExtension = extensions.GetGroupRecordExtensionType();
                }
            }
            else {
                this.create = true;
                this.createType = this.stateUrl.GroupType;
                if (this.createType == GroupType.Table)
                    this.group = new NewGroup();
                if (this.createType == GroupType.View)
                    this.group = new ViewGroup();
            }
        }

        private void PopulateView() {
            NemoJsLibrary njl = new NemoJsLibrary();
            njl.IncludePopup();
            njl.IncludeScroller();
            njl.IncludeJQueryUI();
            njl.IncludeJQueryPrettySelect();
            njl.IncludeFile("nemo.manager.group");

            if (this.create) {
                if (this.createType == GroupType.Table)
                    this.ltlHeaderName.Text = "Nowa grupa";
                else
                    this.ltlHeaderName.Text = "Nowy widok";
            }
            else
                this.ltlHeaderName.Text = String.Format("Edycja {2} „{0}” ({1})", this.group.Name, this.group.SystemName, (this.group.Type == GroupType.Table) ? "grupy" : "widoku");

            this.lnkCancel.NavigateUrl = this.GetEndUrl();


            if (!this.create) {
                this.nemoTabNemo.Visible = true;
                this.nemoTabNemo.AddLinkMenuItem("Ogólne", String.Empty, true);

                NemoUrl columnsUrl = new NemoUrl(NemoUrlView.ManageColumns);
                columnsUrl.GroupId = this.group.Id;
                columnsUrl.MissingInReturnHistory = true;
                this.nemoTabNemo.AddLinkMenuItem("Kolumny", columnsUrl.GetUrl());

                this.nemoTabNemo.AddLinkMenuItem("Generator XML", "#xml");

                this.pnlSystemName.Visible = false;
            }

            if (this.group.Type == GroupType.View) {
                this.pnlViewDeclaration.Visible = true;
                if (!this.create)
                    this.validatorViewDeclarationRequired.Enabled = false;
            }

            this.txtSystemName.Text = this.group.SystemName;
            this.txtDisplayName.Text = this.group.Name;
            this.txtIdentyficator.Text = this.group.Identyficator;

            if (this.group.Type == GroupType.Table) {
                this.SetAutoCompleteOfExtension(this.pnlGroupExtension, this.txtGroupExtension, typeof(GroupExtension), this.groupExtension);
                this.SetAutoCompleteOfExtension(this.pnlGroupRecordExtension, this.txtGroupRecordExtension, typeof(RecordExtension), this.recordExtension);
                this.radioReadOnly.SelectedValue = this.group.ReadOnly ? "true" : "false";
                this.radioSupportTranslate.SelectedValue = this.group.EnableTranslate ? "true" : "false";
            }
            else {
                this.pnlGroupExtension.Visible = false;
                this.pnlGroupRecordExtension.Visible = false;
                this.pnlReadOnly.Visible = false;
                this.pnlSupportTranslate.Visible = false;
            }

        }

        private void SetAutoCompleteOfExtension(Panel wrapper, TextBox userInput, Type extensionType, Type definedExtension) {
            Type[] sourceTypes = extensionType.GetAsignableTypes();
            if (sourceTypes.Length == 0)
                wrapper.Visible = false;
            else {
                if (definedExtension != null)
                    userInput.Text = definedExtension.GetShortAssemblyQualifiedName();
                HiddenField sourceField = new HiddenField();
                wrapper.Controls.Add(sourceField);
                userInput.Attributes.Add("data-completesource", sourceField.ClientID);
                sourceField.Value = String.Join(";", sourceTypes.Select(t => t.GetShortAssemblyQualifiedName()).ToArray());
            }
        }

        private string GetEndUrl() {
            if (this.stateUrl.HaveReturnUrl)
                return this.stateUrl.RequestReturnUrl;
            else {
                return "~/Manager/";
            }
        }

        protected void Save_Click(object sender, EventArgs e) {
            if (this.IsValid) {

                this.group.Name = Request[this.txtDisplayName.UniqueID];
                this.group.Identyficator = Request[this.txtIdentyficator.UniqueID];

                if (this.group.Type == GroupType.Table) {
                    this.group.ReadOnly = Request[this.radioReadOnly.UniqueID] == "true";
                    this.group.EnableTranslate = Request[this.radioSupportTranslate.UniqueID] != "false";
                }

                if (this.create) {
                    if (this.createType == GroupType.Table) {
                        (this.group as NewGroup).SaveNew(Request[this.txtSystemName.UniqueID]);
                        this.extensions = new Extensions(this.group);
                    }
                    else
                        (this.group as ViewGroup).SaveNew(Request[this.txtSystemName.UniqueID], Request[this.txtViewDeclaration.UniqueID]);
                }
                else
                    this.group.Save();

                if (group.Type == GroupType.Table) {
                    string sGroupExtension = Request[this.txtGroupExtension.UniqueID];
                    Type groupExtensionType = null;
                    if (!String.IsNullOrEmpty(sGroupExtension))
                        groupExtensionType = Type.GetType(sGroupExtension);
                    this.extensions.ChangeGroupExtension(groupExtensionType);

                    string sRecordExtension = Request[this.txtGroupRecordExtension.UniqueID];
                    Type recordExtensionType = null;
                    if (!String.IsNullOrEmpty(sRecordExtension))
                        recordExtensionType = Type.GetType(sRecordExtension);
                    this.extensions.ChangeGroupRecordExtension(recordExtensionType);
                }
                //NemoUrl url = new NemoUrl(NemoUrlView.Manager);
                //url.ShowMessage(NemoMessage.SaveOk);
                //url.AddReturnUrl = false;
                if (this.create) {
                    NemoUrl url = new NemoUrl(NemoUrlView.EditGroup);
                    url.GroupId = this.group.Id;
                    url.GroupType = this.group.Type;
                    url.ShowMessage(NemoMessage.SaveOk);
                    url.MissingInReturnHistory = true;
                    Response.Redirect(url.GetUrl());
                }
                else
                    Response.Redirect("/Nemo/Manager/Default.aspx?message=saveOk");
            }
        }

        protected void Validate_CheckGroupExist(object source, ServerValidateEventArgs args) {
            args.IsValid = !this.factory.GetGroupOperators().CheckName(args.Value);
        }

        protected void Validate_CheckGroupExtension(object source, ServerValidateEventArgs args) {
            this.Validate_CheckExtension(source, args, typeof(GroupExtension));
        }

        protected void Validate_CheckGroupRecordExtension(object source, ServerValidateEventArgs args) {
            this.Validate_CheckExtension(source, args, typeof(RecordExtension));
        }

        private void Validate_CheckExtension(object source, ServerValidateEventArgs args, Type extensionType) {
            Type t = Type.GetType(args.Value, false);
            args.IsValid = t != null && extensionType.IsAssignableFrom(t);
        }

        protected void Validate_CheckViewDeclaration(object source, ServerValidateEventArgs args) {
            args.IsValid = Factory.Instance().GetGroupOperators().CheckViewDeclaration(args.Value);
        }

        #endregion

    }
}